/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2017年8月31日
 * V4.0
 */
package com.jphenix.webserver.service;

import com.jphenix.servlet.parent.ServiceBeanParent;
import com.jphenix.standard.docs.BeanInfo;
import com.jphenix.standard.docs.ClassInfo;
import com.jphenix.standard.docs.Running;
import com.jphenix.webserver.instancea.Serve;

import javax.servlet.Filter;

/**
 * 内置Web服务器启动类
 * 
 * com.jphenix.webserver.service.ServStarter
 * 
 * 说明：在生产环境中，通常使用主流的Servlet容器，比如Tomcat、Weblogic等等。但是有些功能，
 * 出于安全考虑，是不能对外开放的，比如港口推送补丁，查看实时日志，文件管理等等。
 * 
 * 考虑启用内置的Web服务器，对于程序这块可以做到不做任何改动即可只开放内部端口使用，
 * 而不开放给外网访问。
 * 
 * 在配置文件中配置  <native_web_server_port>81</native_web_server_port> 即可启动内部web服务
 * 
 * 如果在本地开发时，配置了内部web服务没起作用，估计是在本地项目文件夹有一个开发配置文件，没有在这里配置
 * 
 * 如果再在配置文件中配置  <disable_outsite_develop>1</disable_outsite_develop> 外部端口访问程序，就无法
 * 使用继承AdminBeanParent父类的程序了，实现了避免外部访问高风险功能。
 * 
 * 应客户要求： 不愿再输入授权码，但是我们必须要考虑整个系统的安全性，于是做了以下改动：
 * 
 *       在TFO_DEV_USER表中增加了 god_rule 字段，为1时，该用户登录后，无需再输入授权码即可访问高风险操作。
 *       
 *       即使无需输入授权码可以访问高风险操作，也只能启用内部WEB服务，在内部WEB服务监听端口上才能正常访问。
 *       
 * 2019-01-24 修改了代码中涉及到的父类路径
 * 
 * @author MBG
 * 2017年8月31日
 */
@ClassInfo({"2019-01-24 16:54","内置Web服务器启动类"})
@BeanInfo({"nativewebservstarter","0","","","1"})
@Running({"90","","","stop"}) //不在这里做启动初始化，在主过滤器设置完虚拟路径后，在做初始化
public class ServStarter extends ServiceBeanParent {

	private int port           = -1;   //监听端口号
	private String contextPath = null; //虚拟路径
	private Serve serve        = null; //内置web服务类
	private ServThread st      = null; //启动服务线程
	
	/**
	 * 启动服务线程
	 * @author MBG
	 * 2017年8月31日
	 */
	private class ServThread extends Thread {
		
		private Filter filter = null; //主过滤器
		
		/**
		 * 构造函数
		 * @author MBG
		 */
		public ServThread(Filter filter) {
			super("ServStarter-ServThread");
			this.filter = filter;
		}
		
		/**
		 * 覆盖函数
		 */
		@Override
        public void run() {
			//构建
			serve = new Serve();
			try {
			  serve.startup(port,contextPath,filter);
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 构造函数
	 * @author MBG
	 */
	public ServStarter() {
		super();
	}
	
	/**
	 * 设置监听端口号
	 * @param port 监听端口号
	 * 2017年8月31日
	 * @author MBG
	 */
	public void setPort(int port) {
		this.port = port;
	}
	
	/**
	 * 获取监听端口号
	 * @return 监听端口号
	 * 2017年8月31日
	 * @author MBG
	 */
	public int getPort() {
		return port;
	}
	
	/**
	 * 设置虚拟路径
	 * @param contextPath 虚拟路径
	 * 2017年8月31日
	 * @author MBG
	 */
	public void setContextPath(String contextPath) {
		this.contextPath = contextPath;
	}
	
	/**
	 * 获取虚拟路径
	 * @return 虚拟路径
	 * 2017年8月31日
	 * @author MBG
	 */
	public String getContextPath() {
		return contextPath;
	}
	
	/**
	 * 启动服务
	 * @throws Exception 执行异常
	 * 2017年8月31日
	 * @author MBG
	 */
	public void start(Filter filter) throws Exception {
		if(port<0) {
			return;
		}
		//构建启动服务现成
		st = new ServThread(filter);
		
		//执行启动服务
		st.start();
	}
	
	/**
	 * 停止服务
	 * 2017年8月31日
	 * @author MBG
	 */
	@SuppressWarnings("deprecation")
	public void stop(){
		try {
			serve.stop();
		}catch(Exception e) {}
		try {
			st.stop();
		}catch(Exception e) {}
		st = null;
		
	}
}
